package com.lagou.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.rpc.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;


@Activate(group = {CommonConstants.PROVIDER})
public class TPMonitorFilter implements Filter {

    private static ConcurrentMap<String, CopyOnWriteArrayList<List<Long>>> map = new ConcurrentHashMap<String, CopyOnWriteArrayList<List<Long>>>();

    // 记录5秒打印时间
    private static ConcurrentMap<String, Long> mapPrintTime = new ConcurrentHashMap<String, Long>();

    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        String methodName = invocation.getMethodName();
        CopyOnWriteArrayList<List<Long>> outList = map.get(methodName);
        Long printTime = mapPrintTime.get(methodName);
        if (printTime == null){
            printTime = System.currentTimeMillis();
            mapPrintTime.put(methodName,printTime);
        }
        long startTime = System.currentTimeMillis();
         // 第一次数据是空，初始化
        if (outList == null){
            outList = new CopyOnWriteArrayList<List<Long>>();
            ArrayList<Long> longs = new ArrayList<Long>();
            outList.add(longs);
            map.put(methodName,outList);
        }
        // 判断5秒时间 添加一个时间
        if ((startTime - printTime )> 5000){
            ArrayList<Long> longs = new ArrayList<Long>();
            outList.add(longs);
            if (outList.size()>12){
                outList.remove(0);
            }

            // 重置时间
            printTime = startTime;
            mapPrintTime.put(methodName,printTime);

            // 统计耗时
            ArrayList<Long> longArrayList = new ArrayList<Long>();
            for (List<Long> list:outList){
                longArrayList.addAll(list);
            }
            CollectionUtils.sort(longArrayList);
            Double v90 = longArrayList.size() * 0.9;
            int i90 = v90.intValue() -1;
            System.out.println(methodName+ " TP90 = "+longArrayList.get(i90));

            Double v99 = longArrayList.size() * 0.99;
            int i99 = v99.intValue() -1;
            System.out.println(methodName+ " TP99 = "+ longArrayList.get(i99));

        }

        try {
            // 执行方法
            return invoker.invoke(invocation);
        } finally {
            long useTime = System.currentTimeMillis() - startTime;
            // 获取最后一个list，放入rpc耗时
            List<Long> longs = outList.get(outList.size() - 1);
            longs.add(useTime);
//            System.out.println(methodName+" use time = " + useTime);
        }

    }


}
